package com.zbc.manager;

import io.minio.*;
import io.minio.http.Method;
import io.minio.messages.Bucket;
import io.minio.messages.Item;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import org.springframework.stereotype.Component;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;


/**
 * Minio 管理类
 *
 * @author fangyu
 * @version v1.0.0
 * @since 2025/9/2 23:08
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class MinioManager {
    private final MinioClient minioClient;

    /**
     * 查看存储bucket是否存在
     *
     * @param bucketName 存储桶名称
     * @return boolean 存在返回true，否则false
     */
    public Boolean bucketExists(String bucketName) {
        try {
            return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
        } catch (Exception e) {
            log.error("检查Bucket存在失败: {}", e.getMessage(), e);
            return false;
        }
    }

    /**
     * 创建存储bucket
     *
     * @param bucketName 存储桶名称
     * @return Boolean 创建成功返回true，否则false
     */
    public Boolean makeBucket(String bucketName) {
        try {
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
            return true;
        } catch (Exception e) {
            log.error("创建Bucket失败: {}", e.getMessage(), e);
            return false;
        }
    }

    /**
     * 删除存储bucket
     *
     * @param bucketName 存储桶名称
     * @return Boolean 删除成功返回true，否则false
     */
    public Boolean removeBucket(String bucketName) {
        try {
            minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());
            return true;
        } catch (Exception e) {
            log.error("删除Bucket失败: {}", e.getMessage(), e);
            return false;
        }
    }

    /**
     * 获取全部bucket列表
     *
     * @return List<Bucket> 存储桶列表，失败返回空列表
     */
    public List<Bucket> getAllBuckets() {
        try {
            return minioClient.listBuckets();
        } catch (Exception e) {
            log.error("获取Bucket列表失败: {}", e.getMessage(), e);
            return Collections.emptyList();
        }
    }

    /**
     * 上传本地文件到 MinIO
     *
     * @param bucketName 存储桶名称
     * @param objectName 对象名称
     * @param file       本地文件
     * @return ObjectWriteResponse 上传文件响应
     */
    public ObjectWriteResponse putObject(String bucketName, String objectName, File file) throws Exception {
        return minioClient.uploadObject(
                UploadObjectArgs.builder()
                        .bucket(bucketName)
                        .object(objectName)
                        .filename(file.getAbsolutePath())
                        .build());
    }

    /**
     * 下载文件到本地
     *
     * @param bucketName 存储桶名称
     * @param objectName 对象名称
     * @return GetObjectResponse 下载文件响应
     */
    public GetObjectResponse getObject(String bucketName, String objectName) throws Exception {
        return minioClient.getObject(
                GetObjectArgs.builder()
                        .bucket(bucketName)
                        .object(objectName)
                        .build());
    }

    /**
     * 获取文件列表
     *
     * @param bucketName 存储桶名称
     * @return List<Item> 文件列表，失败返回空列表
     */
    public List<Item> listObjects(String bucketName) throws Exception {
        List<Item> objects = new ArrayList<>();
        Iterable<Result<Item>> results = minioClient.listObjects(
                ListObjectsArgs.builder().bucket(bucketName).build());

        for (Result<Item> result : results) {
            objects.add(result.get());
        }
        return objects;
    }

    /**
     * 删除文件
     *
     * @param bucketName 存储桶名称
     * @param objectName 对象名称
     */
    public void removeObject(String bucketName, String objectName) throws Exception {
        minioClient.removeObject(
                RemoveObjectArgs.builder()
                        .bucket(bucketName)
                        .object(objectName)
                        .build());
    }

    /**
     * 生成预签名 URL（用于临时访问）
     *
     * @param bucketName 存储桶名称
     * @param objectName 对象名称
     * @param expiry     过期时间（单位：分钟）
     * @return 预签名URL
     */
    public String getPresignedObjectUrl(String bucketName, String objectName, int expiry) throws Exception {
        return minioClient.getPresignedObjectUrl(
                GetPresignedObjectUrlArgs.builder()
                        .method(Method.GET)
                        .bucket(bucketName)
                        .object(objectName)
                        .expiry(expiry, TimeUnit.MINUTES)
                        .build());
    }
}
